package edu.ccut.saturn.studio.saturndata.page;

import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.MasterDetailsBlock;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;


import edu.ccut.saturn.studio.core.util.eclipse.Messages;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnProjectUtil;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnDialogUtil;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnSWTUtils;
import edu.ccut.saturn.studio.saturndata.dialog.DataItemAddByCustemDialog;
import edu.ccut.saturn.studio.saturndata.dialog.DataItemRenameDialog;
import edu.ccut.saturn.studio.saturndata.dialog.DateItemAddByTableDialog;
import edu.ccut.saturn.studio.saturndata.editor.SaturnDataEditor;
import edu.ccut.saturn.studio.saturndata.model.DataItem;
import edu.ccut.saturn.studio.saturndata.model.SaturnData;
import edu.ccut.saturn.studio.saturndata.model.SaturnDataModel;

/**
 * 字段详细信息
 * 
 * @author 谷钰
 * 
 * @version 1.0 2008.12.09
 * 
 */
public class DateItemMasterDetailsBlock extends MasterDetailsBlock {
	private DataItemPage page;
	private Table table;
	private TableViewer viewer;
	private DataItemDetailsPage detailsPage;

	private Shell shell;
	private SaturnData saturnData;
	private Button addButton;
	private Button addnewcolmnButton;
	private Button delButton;
	private Button renameButton;
	private SaturnDataModel saturnDataModel;

	public DateItemMasterDetailsBlock(DataItemPage fieldPage,
			SaturnDataEditor editor) {

		this.page = fieldPage;
		saturnDataModel = fieldPage.getSaturnDataModel();
		saturnData = saturnDataModel.getSaturnData();
		this.shell = this.page.getEditor().getSite().getShell();
	}

	protected void registerPages(DetailsPart detailsPart) {
		detailsPage = new DataItemDetailsPage(page);
		detailsPart.registerPage(DataItem.class, detailsPage);
	}

	protected void createMasterPart(final IManagedForm managedForm,
			Composite parent) {

		FormToolkit toolkit = managedForm.getToolkit();
		Section section = toolkit.createSection(parent, Section.DESCRIPTION
				| ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED
				| ExpandableComposite.TITLE_BAR);
		section.setText(Messages.getString("ScrolledPropertiesBlock.fieldname")); //$NON-NLS-1$

		section
				.setDescription(Messages
						.getString("ScrolledPropertiesBlock.choosefieldname")); //$NON-NLS-1$
		section.marginWidth = 10;
		section.marginHeight = 5;

		toolkit.createCompositeSeparator(section);

		Composite client = toolkit.createComposite(section, SWT.WRAP);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		client.setLayout(layout);

		table = toolkit.createTable(client, SWT.FULL_SELECTION);
		GridData gridData1 = new GridData(SWT.FILL, SWT.FILL, true, true);
		gridData1.horizontalIndent = 0;
		gridData1.heightHint = 100;
		gridData1.verticalSpan = 6;
		table.setLayoutData(gridData1);

		/*
		 * 为当前parent内，toolkit所创建的widget添加边框。如果widget已经设置了SWT.BORDER， 则不会再为其添加边框。
		 */
		toolkit.paintBordersFor(client);

		addButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.add"), SWT.PUSH); //$NON-NLS-1$
		GridData gridDataadd = new GridData(97, 22);
		addButton.setLayoutData(gridDataadd);
		// addButton.setLayoutData(new
		// GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				doAddDataItemByTable();
			}
		});

		addnewcolmnButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.adduserdefinedfield"), SWT.PUSH); //$NON-NLS-1$
		addnewcolmnButton.setLayoutData(new GridData(
				GridData.VERTICAL_ALIGN_BEGINNING));
		addnewcolmnButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {

				openAddNewDialog();
			}
		});

		delButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.delete"), SWT.PUSH); //$NON-NLS-1$
		delButton.setLayoutData(gridDataadd);
		delButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				doDeleteDataItem();
			}
		});

		renameButton = toolkit
				.createButton(
						client,
						Messages.getString("ScrolledPropertiesBlock.rename"), SWT.PUSH | SWT.ARROW_UP); //$NON-NLS-1$
		GridData gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
		gridData.widthHint = 97;
		gridData.heightHint = 22;
		renameButton.setLayoutData(gridData);
		renameButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				openRenameDialog();
			}
		});

		/*
		 * IFormPart管理了整个Part的dirty state, saving, commit, focus, selection
		 * changes等等这样的事件。 并不是form中的每一个control都需要成为一个form
		 * part，最好将一组control通过实现IFormPart变成一个Part.
		 * 一般来说Section就是一个自然形成的组，所以Eclipse Form提供了一个SectionPart的实现，它包含一个Section
		 * 的实例。
		 */

		final SectionPart spart = new SectionPart(section, toolkit, SWT.NONE);
		managedForm.addPart(spart);
		viewer = new TableViewer(table);
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection selected = (IStructuredSelection) viewer
						.getSelection();
				if (selected.getFirstElement() instanceof DataItem) {
					addButton.setEnabled(true);
					delButton.setEnabled(true);
					renameButton.setEnabled(true);

					managedForm.fireSelectionChanged(spart, event
							.getSelection());
				}

			}
		});

		viewer
				.setContentProvider(new SaturnSWTUtils.SaturnTableViewerDefaultContentProvider());
		viewer
				.setLabelProvider(new SaturnSWTUtils.SaturnTableViewerDefaultLabelProvider() {
					public String getColumnText(Object obj, int index) {
						DataItem dataItem = (DataItem) obj;

						if (index == 0) {
							return dataItem.getName();
						}
						return ""; //$NON-NLS-1$
					}
				});
		viewer.setInput(saturnData.getDataItemList());

		addButton.setEnabled(true);
		delButton.setEnabled(false);
		renameButton.setEnabled(false);
		/**
		 * Sets the client of this expandable composite. The client must not be
		 * null and must be a direct child of this container.
		 */
		section.setClient(client);
	}

	private void doAddDataItemByTable() {
		DateItemAddByTableDialog addDBDialog = new DateItemAddByTableDialog(
				shell, saturnData.getConnectionName());

		if (addDBDialog.open() == IDialogConstants.OK_ID) {
			List<DataItem> checkDataItems = addDBDialog.getCheckedDataItems();

			List<DataItem> dataItems = saturnData.getDataItemList();

			DataItem lastAddDataItem = null;

			for (DataItem checkDataItem : checkDataItems) {
				if (!this.hasSameDataItemName(checkDataItem, dataItems)) {
					saturnDataModel.addDataItem(checkDataItem);

					lastAddDataItem = checkDataItem;
				}
			}

			if (lastAddDataItem != null) {
				viewer.setInput(dataItems);
				viewer.setSelection(new StructuredSelection(lastAddDataItem));
			}

		}

		SaturnProjectUtil.refreshProject(DateItemMasterDetailsBlock.this.page
				.getEditorInput());
	}

	private boolean hasSameDataItemName(DataItem checkedDataItem,
			List<DataItem> dataItems) {

		for (DataItem dataItem : dataItems) {
			if (checkedDataItem.getName().equals(dataItem.getName())) {
				SaturnDialogUtil
						.openInformation(
								shell,
								Messages
										.getString("ScrolledPropertiesBlock.dataitemnamecannotrepeat") + "name=\"" + checkedDataItem.getName() + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				return true;
			}
		}

		return false;
	}

	private void openAddNewDialog() {
		DataItemAddByCustemDialog addNewColumnDialog = new DataItemAddByCustemDialog(shell);

		if (addNewColumnDialog.open() == IDialogConstants.OK_ID) {
			DataItem fieldVo = addNewColumnDialog.getDataItem();

			List<DataItem> dataItems = saturnData.getDataItemList();
			if (!this.hasSameDataItemName(fieldVo, dataItems)) {
				saturnDataModel.addDataItem(fieldVo);
			}

			if (fieldVo != null) {
				viewer.setInput(dataItems);
				viewer.setSelection(new StructuredSelection(fieldVo));
			}

			viewer.setInput(saturnData.getDataItemList());
			viewer.setSelection(new StructuredSelection(fieldVo));
		}

		SaturnProjectUtil.refreshProject(DateItemMasterDetailsBlock.this.page
				.getEditorInput());
	}

	private void doDeleteDataItem() {
		IStructuredSelection selection = (IStructuredSelection) viewer
				.getSelection();

		if (selection.isEmpty()) {
			SaturnDialogUtil.openInformation(null,
					Messages.getString("ScrolledPropertiesBlock.choosedeleteitem")); //$NON-NLS-1$

			return;
		}

		DataItem dataItem = (DataItem) selection.getFirstElement();
		if (SaturnDialogUtil
				.openConfirm(
						null,
						Messages.getString("ScrolledPropertiesBlock.remend"), Messages.getString("ScrolledPropertiesBlock.confirmdeleteitem"))) { //$NON-NLS-1$ //$NON-NLS-2$

			List<DataItem> dataItems = saturnData.getDataItemList();

			int i = dataItems.indexOf(dataItem);

			saturnDataModel.removeDataItem(dataItem);
			viewer.setInput(dataItems);

			if (i <= dataItems.size() - 1) {
				viewer.setSelection(new StructuredSelection(dataItems.get(i)));
			} else if (dataItems.size() >= 1 && i == dataItems.size()) {
				viewer.setSelection(new StructuredSelection(dataItems
						.get(i - 1)));
			} else {
				detailsPage.clear();
			}
			
			SaturnProjectUtil.refreshProject(DateItemMasterDetailsBlock.this.page
					.getEditorInput());

		}
	}

	private void openRenameDialog() {
		List<DataItem> dataItems = saturnData.getDataItemList();

		DataItemRenameDialog fieldNameDialog = new DataItemRenameDialog(shell, dataItems);
		DataItem dataItem = (DataItem) dataItems.get(viewer.getTable()
				.getSelectionIndex());

		fieldNameDialog.setName(dataItem.getName());

		if (fieldNameDialog.open() == Window.OK) {
			String id = dataItem.getId();
			
			dataItem.setName(fieldNameDialog.getName());
			viewer.setInput(dataItems);
			saturnDataModel.changeFiledAttributeValue(id,
					"name", dataItem.getName());//$NON-NLS-1$

			SaturnProjectUtil.refreshProject(DateItemMasterDetailsBlock.this.page
					.getEditorInput());
		}
	}

	public void setConnectname(String connectname) {
		saturnData.setConnectionName(connectname);
	}

	protected void createToolBarActions(IManagedForm managedForm) {
		final ScrolledForm form = managedForm.getForm();
		Action haction = new Action(
				Messages.getString("ScrolledPropertiesBlock.level"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.HORIZONTAL);
				form.reflow(true);
			}
		};
		haction.setChecked(true);
		haction
				.setToolTipText(Messages
						.getString("ScrolledPropertiesBlock.landscapeorietation")); //$NON-NLS-1$

		Action vaction = new Action(
				Messages.getString("ScrolledPropertiesBlock.vertical"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.VERTICAL);
				form.reflow(true);
			}
		};
		vaction.setChecked(false);
		vaction
				.setToolTipText(Messages
						.getString("ScrolledPropertiesBlock.portritorietation")); //$NON-NLS-1$

		form.getToolBarManager().add(haction);
		form.getToolBarManager().add(vaction);
	}
}